package com.psychologyCommunity.Community.service;

import com.psychologyCommunity.Community.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;

@Service
public class LikeService {
    @Autowired
    private RedisTemplate redisTemplate;
    //点赞  --userId这个是点赞的那个人 ，而我们统计的是被赞的那个人数量，即帖子的作者 ,
    //为什么不访问数据库拿entityUserId，因为我们本来就是用的redis，性能比较高，然后你返回数据库，又把性能拉低了
    public void like(int userId,int entityType,int entityId,int entityUserId) {
//        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
//        //判断在不在集合里
//        boolean isMember = redisTemplate.opsForSet().isMember(entityLikeKey, entityId);
//        if (isMember) { //如果存在集合中，就说明点过赞了，再次点赞就取消 --即移除集合
//            redisTemplate.opsForSet().remove(entityLikeKey, userId);
//        } else {
//            //要是没存在集合中 说明没点过赞，就加入集合
//            redisTemplate.opsForSet().add(entityLikeKey, userId);
//        }
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String entityLikeKey=RedisKeyUtil.getEntityLikeKey(entityType,entityId);
                String userLikeKey=RedisKeyUtil.getUserLikeKey(entityUserId);
//      //    isMember(K key, Object o)---检查给定的元素是否在变量中。 -要注意这是在redis中查询，要放在事务之外
                boolean isMember=operations.opsForSet().isMember(entityLikeKey,userId);
                //开启 和执行事务 --在这中间进行两次修改操作
                operations.multi();
                if(isMember){  ////如果存在集合中，就说明点过赞了，再次点赞就取消
                    operations.opsForSet().remove(entityLikeKey,userId);//以实体为key的数据做处理做出操作
                    operations.opsForValue().decrement(userLikeKey);//以user为key的数据做处理
                }else{
                    operations.opsForSet().add(entityLikeKey,userId);
                    operations.opsForValue().increment(userLikeKey);
                }
                return operations.exec(); }
        }); }
    //查询某实体点赞的数量
    public long findEntityLikeCount(int entityType,int entityId){
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
        return redisTemplate.opsForSet().size(entityLikeKey); }
    //查询某人对某实体的点赞状态 为什么不用布尔类型，而用int类型，因为之后进行功能扩展 可能还有其他状态比如说踩 将来可以让他返回-1
    public  int findEntityLikeStatus(int userId,int entityType,int entityId){
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
        return redisTemplate.opsForSet().isMember(entityLikeKey,userId)?1:0;//如果返回1表示点了赞，如果为0表示没有点赞
    }

    //查询某个用户获得的赞
    public int findUserLikeCount(int UserId){
        String UserLikeKey=RedisKeyUtil.getUserLikeKey(UserId);
        Integer count= (Integer) redisTemplate.opsForValue().get(UserLikeKey);
        //返回时要做一个判断，为null就显示为0，否则转换为整数
        return count==null?0:count.intValue();
    }

}
